package com.xbongbong.paas.gateway;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.DoubleSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.util.Locale;


/**
 * PAAS 网关系统
 * @author kaka
 * @date 2018-7-29 15:31
 *
 */
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
@RestController
@EnableAsync
@ComponentScan(basePackages={"com.xbongbong"})
@EnableFeignClients(basePackages = {"com.xbongbong.paas.gateway.manager.feign"})
public class StartGatewayApplication{

	private static final Logger LOG = LoggerFactory.getLogger(StartGatewayApplication.class);

	public static void main(String[] args) {
		try {
			// fastJson double位数，设成最多的6位，避免科学计数法
			SerializeConfig config = SerializeConfig.getGlobalInstance();
			config.put(Double.class, new DoubleSerializer("#.######"));
			// 设置系统线程默认语言包，LocaleContextHolder spring工具
			LocaleContextHolder.setDefaultLocale(Locale.CHINA);

			SpringApplication.run(StartGatewayApplication.class, args);
		} catch (Exception e) {
			LOG.error("StartGatewayApplication启动报错:", e);
		}
	}

	/**
	 * 服务熔断处理，返回熔断错误信息
	 * @return 返回服务熔断后的错误提示信息
	 */
	@RequestMapping("/serviceFallback")
	public String serviceFallback() {
		return formatFallbackError();
	}

	/**
	 * 自定义限流标志的key，多个维度可以从这里入手
	 * exchange对象中获取服务ID、请求信息，用户信息等
	 */
	@Bean
	public KeyResolver ipKeyResolver() {
		return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
	}

	/**
	 * 构建熔断错误返回数据，目前格式如下
	 * {
	 *     "code": -1,
	 *     "msg": "服务繁忙,请稍后再试",
	 *     "empty": true,
	 *     "success": false,
	 *     "totalCount": 0
	 * }
	 *
	 * @author kaka
	 * @time 2018-8-1 10:55
	 */
	private String formatFallbackError() {
		XbbResponse verifyError = new XbbResponse(ErrorCodeEnum.API_FALLBACK);
		return JSON.toJSONString(verifyError);
	}
}